package com.pgeg.mixin.mana;

import com.mojang.blaze3d.systems.RenderSystem;
import com.pgeg.api.mana.IManaHandler;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.MathHelper;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.Random;

import static com.pgeg.util.Reference.MANA_ICONS;

@Mixin(InGameHud.class)
public abstract class ManaBarMixin extends DrawableHelper {

    @Shadow @Final private MinecraftClient client;

    @Shadow private int scaledWidth;

    @Shadow private int scaledHeight;

    @Shadow @Final private Random random;

    @Inject(method = "renderStatusBars", at = @At("RETURN"))
    private void renderManaBar(MatrixStack matrices, CallbackInfo ci) {
        if (this.client.getCameraEntity() instanceof PlayerEntity) {
            PlayerEntity player = (PlayerEntity) this.client.getCameraEntity();
            IManaHandler handler = (IManaHandler) player;
            if (player != null) {
                int mana = MathHelper.ceil(handler.getMana());
                int barX = this.scaledWidth / 2 - 91;
                int barY = this.scaledHeight - 39;
                int manaPerStar = (int) handler.getMaxMana() / 10;
                int maxHealth = MathHelper.ceil((player.getAttributeValue(EntityAttributes.GENERIC_MAX_HEALTH)
                        + player.getAbsorptionAmount()) / 2.0F / 10.0F);
                RenderSystem.setShaderTexture(0, MANA_ICONS);
                int x;

                for (x = 9; x >= 0; --x) {
                    int drawX = barX + x * 8;
                    int drawY = barY - (maxHealth - 1) * Math.max(10 - (maxHealth - 2), 3) - 10;
                    if (player.getArmor() > 0) {
                        drawY -= 10;
                    }
                    if (MathHelper.ceil(mana) <= 2 * manaPerStar) {
                        drawY += this.random.nextInt(2);
                    }
                    this.drawTexture(matrices, drawX, drawY, 0, 0, 9, 9);
                    if (x * manaPerStar + 1 < mana) {
                        this.drawTexture(matrices, drawX, drawY, 9, 0, 9, 9);
                    } else if (x * manaPerStar + 1 == mana) {
                        this.drawTexture(matrices, drawX, drawY, 18, 0, 9, 9);
                    }
                }
            }
        }
    }
}
